package com.itjiange.controller;

import com.itjiange.common.BaseResponse;
import com.itjiange.constant.CommonConstant;
import com.itjiange.model.pojo.FileInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * 文件接口
 *
 * @author ItJiange
 * @date 2023/10/31
 */
@RestController
@RequestMapping("/file")
public class FileController {

    @Value("${myServer.rootPath}")
    private String servicePath; // 服务器文件存储路径

    /**
     * 获取服务器路径下所有文件信息
     *
     * @return
     */
    @GetMapping("/getAllFiles")
    public BaseResponse<List<FileInfo>> getAllFiles() {
        // 创建 File 对象，获取指定目录下的所有文件
        File file = new File(servicePath);
        File[] files = file.listFiles();
        // 创建文件集合
        List<FileInfo> fileInfoList = new LinkedList<>();
        // 遍历所有文件，并封装为 FileInfo 对象，存入集合
        for (File f : files) {
            // 格式化文件创建时间
            Date date = new Date(file.lastModified());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            // 创建 FileInfo 对象
            FileInfo fileInfo = new FileInfo();
            fileInfo.setFileName(f.getName());
            fileInfo.setFileSize(String.format("%.2f", (f.length() / 1024.0)) + "KB");
            fileInfo.setCreateTime(sdf.format(date));
            // 将 fileInfo 对象存入集合中
            fileInfoList.add(fileInfo);
        }
        return new BaseResponse<>(CommonConstant.SUCCESS, fileInfoList);
    }

    /**
     * 上传文件
     *
     * @return
     */
    @PostMapping("/uploadFiles")
    public BaseResponse<String> uploadFiles(@RequestParam("file") MultipartFile[] files) {
        for (MultipartFile file : files) {
            String fileName = file.getOriginalFilename(); // 文件名
            String fileUploadPath = servicePath + File.separator + fileName;
            // 如果该路径下文件存在未创建的文件夹，则直接创建
            File fileCurrent = new File(fileUploadPath);
            if (!fileCurrent.getParentFile().exists()) {
                fileCurrent.getParentFile().mkdirs();
            }
            // 将文件写入指定服务器路径中
            try (InputStream fileInputStream = file.getInputStream(); // 文件输入流
                 FileOutputStream fileOutputStream = new FileOutputStream(fileCurrent);) {
                fileInputStream.transferTo(fileOutputStream);
            } catch (IOException e) {
                e.printStackTrace();
                return new BaseResponse<>(CommonConstant.ERROR, "上传文件失败");
            }
        }
        return new BaseResponse<>(CommonConstant.SUCCESS, "上传文件成功");
    }

    /**
     * 下载文件
     *
     * @return
     */
    @GetMapping("/downloadFile")
    public ResponseEntity<FileSystemResource> downloadFiles(@RequestParam("fileName") String fileName) {
        // 文件所在完整路径
        String downloadPath = servicePath + File.separator + fileName;
        return export(new File(downloadPath));
    }

    // 文件下载方法
    public ResponseEntity<FileSystemResource> export(File file) {
        if (file == null) {
            return null;
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        try {
            headers.add("Content-Disposition", "attachment; filename=" + URLEncoder.encode(file.getName(), "utf-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("Last-Modified", new Date().toString());
        headers.add("ETag", String.valueOf(System.currentTimeMillis()));
        return ResponseEntity
                .ok()
                .headers(headers)
                .contentLength(file.length())
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(new FileSystemResource(file));
    }
}
